import React, { useState, useEffect } from 'react';
import _ from 'lodash';
import { nanoid } from 'nanoid';
import { arrayMoveImmutable } from 'array-move';
import { Button, Form, Input, Radio, Checkbox, Tabs, InputNumber } from 'antd';
import DraggableModal from '@/components/DraggableModal';
import DebounceWrapper from '@/components/DebounceWrapper';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
import { HolderOutlined, MinusCircleOutlined, SettingOutlined } from '@ant-design/icons';
import { defaultColumnWidth } from '../../tableContent';
import styles from './index.less';

const { Group } = Radio;
const layout = {
  labelCol: { span: 5 },
  wrapperCol: { span: 17 },
};
const sizeOptions = [
  { label: '小', value: 'small' },
  { label: '中', value: 'middle' },
  { label: '大', value: 'default' },
];
const DebounceButton = DebounceWrapper(Button);

const ColumnControl = ({ value, onChange }) => {
  const { typeList, filterOptions, filterDictType } = value;

  return (
    <div className={styles.columnControlCheckList}>
      <Checkbox
        checked={_.includes(typeList || [], 'search')}
        onChange={(e) => {
          const nextTypeList = [...(typeList || [])];
          if (e.target.checked) {
            nextTypeList.push('search');
            const filterIndex = _.indexOf(nextTypeList, 'filter');
            if (filterIndex > -1) {
              nextTypeList.splice(filterIndex, 1);
            }
          } else {
            const index = _.indexOf(nextTypeList, 'search');
            if (index > -1) {
              nextTypeList.splice(index, 1);
            }
          }
          onChange({
            typeList: nextTypeList,
            filterOptions: _.indexOf(nextTypeList, 'filter') ? filterOptions : [],
            filterDictType: _.indexOf(nextTypeList, 'filter') ? filterOptions : '',
          });
        }}
      >
        关键字搜索
      </Checkbox>
      <div className={styles.columnControlCheckItem}>
        <Checkbox
          checked={_.includes(typeList || [], 'filter')}
          onChange={(e) => {
            const nextTypeList = [...(typeList || [])];
            if (e.target.checked) {
              nextTypeList.push('filter');
              const searchIndex = _.indexOf(nextTypeList, 'search');
              if (searchIndex > -1) {
                nextTypeList.splice(searchIndex, 1);
              }
            } else {
              const index = _.indexOf(nextTypeList, 'filter');
              if (index > -1) {
                nextTypeList.splice(index, 1);
              }
            }
            onChange({
              typeList: nextTypeList,
              filterOptions: _.includes(nextTypeList, 'filter') ? filterOptions : [],
              filterDictType: _.includes(nextTypeList, 'filter') ? filterDictType : '',
            });
          }}
        >
          筛选操作
        </Checkbox>
        {_.includes(typeList || [], 'filter') && (
          <div className={styles.columnControlCheckItemAttribute}>
            <div className={styles.columnControlCheckItemAttributeTitle}>规则项：</div>
            <Tabs size="small">
              <Tabs.TabPane key="filterDictType" tab="从字典获取">
                <div className={styles.columnControlCheckItemAttributeDict}>
                  <span>字典code:</span>
                  <Input
                    size="small"
                    value={filterDictType || ''}
                    placeholder="输入字典code"
                    onChange={(e) => {
                      onChange({
                        typeList,
                        filterOptions,
                        filterDictType: e.target.value,
                      });
                    }}
                  />
                </div>
              </Tabs.TabPane>
              <Tabs.TabPane key="filterOptions" tab="配置筛选规则">
                <div className={styles.columnControlCheckItemAttributeOptions}>
                  <div className={styles.columnControlCheckItemAttributeOptionsTitle}>
                    <span>选项名</span>
                    <span>选项值</span>
                  </div>
                  {(filterOptions || []).map(({ text, value, id }) => (
                    <div key={id} className={styles.columnControlCheckItemAttributeOptionsList}>
                      <Input
                        size="small"
                        value={text}
                        bordered={false}
                        onChange={(e) => {
                          const nextFilterOptions = [...(filterOptions || [])];
                          const index = _.findIndex(
                            nextFilterOptions,
                            ({ id: currentId }) => currentId === id,
                          );
                          if (index > -1) {
                            nextFilterOptions[index].text = e.target.value;
                          }
                          onChange({
                            typeList,
                            filterOptions: nextFilterOptions,
                            filterDictType,
                          });
                        }}
                      />
                      <Input
                        size="small"
                        value={value}
                        bordered={false}
                        onChange={(e) => {
                          const nextFilterOptions = [...(filterOptions || [])];
                          const index = _.findIndex(
                            nextFilterOptions,
                            ({ id: currentId }) => currentId === id,
                          );
                          if (index > -1) {
                            nextFilterOptions[index].value = e.target.value;
                          }
                          onChange({
                            typeList,
                            filterOptions: nextFilterOptions,
                            filterDictType,
                          });
                        }}
                      />
                    </div>
                  ))}
                  <DebounceButton
                    size="small"
                    type="dashed"
                    onClick={() => {
                      const nextFilterOptions = [...(filterOptions || []), { id: nanoid(12) }];
                      onChange({
                        typeList,
                        filterOptions: nextFilterOptions,
                        filterDictType,
                      });
                    }}
                  >
                    添加选项
                  </DebounceButton>
                </div>
              </Tabs.TabPane>
            </Tabs>
          </div>
        )}
      </div>
      <Checkbox
        checked={_.includes(typeList || [], 'sorter')}
        onChange={(e) => {
          const nextTypeList = [...(typeList || [])];
          if (e.target.checked) {
            nextTypeList.push('sorter');
          } else {
            const index = _.indexOf(nextTypeList, 'sorter');
            if (index > -1) {
              nextTypeList.splice(index, 1);
            }
          }
          onChange({
            typeList: nextTypeList,
            filterOptions,
            filterDictType,
          });
        }}
      >
        排序操作
      </Checkbox>
    </div>
  );
};

const ColumnSettingModal = ({ visibleId, options, setProp, closeModal }) => {
  const [form] = Form.useForm();

  useEffect(() => {
    if (visibleId) {
      form.setFieldsValue({
        width: _.isNumber(options.width) ? options.width : defaultColumnWidth,
        align: _.isString(options.align) ? options.align : 'center',
        columnControl: _.isPlainObject(options.columnControl) ? options.columnControl : {},
      });
    } else {
      form.resetFields();
    }
  }, [visibleId]);

  const handleConfirm = () => {
    form.validateFields().then((values) => {
      setProp((props) => {
        const nextColumns = [...props.columns];
        const index = _.findIndex(nextColumns, ({ id: currentId }) => currentId === visibleId);
        if (index > -1) {
          nextColumns[index] = _.assign({}, nextColumns[index], values);
          props.columns = nextColumns;
        }
      }, 500);
      closeModal();
    });
  };

  return (
    <DraggableModal
      title={`属性设置${options.title ? '（' + options.title + '）' : ''}`}
      visible={!!visibleId}
      onCancel={closeModal}
      footer={[
        <DebounceButton key="cancel" onClick={closeModal}>
          取消
        </DebounceButton>,
        <DebounceButton key="confirm" type="primary" onClick={handleConfirm}>
          确定
        </DebounceButton>,
      ]}
    >
      <Form {...layout} form={form} name="pro-table-column-attribute">
        <Form.Item name="width" label="列宽度" initialValue={defaultColumnWidth}>
          <InputNumber placeholder={'请输入列宽度'} />
        </Form.Item>
        <Form.Item name="align" label="排列方式">
          <Group>
            <Radio value="left">靠左</Radio>
            <Radio value="center">居中</Radio>
            <Radio value="right">靠右</Radio>
          </Group>
        </Form.Item>
        <Form.Item name="columnControl" label="列操作" initialValue={{}}>
          <ColumnControl />
        </Form.Item>
      </Form>
    </DraggableModal>
  );
};

const SortableIcon = SortableHandle(HolderOutlined);
const SortableListItem = SortableElement((props) => (
  <div {...props} className={styles.rowListItem} />
));
const SortableListContainer = SortableContainer((props) => (
  <div {...props} className={styles.rowListContainer} />
));
const SortableColumns = ({ columns, setProp }) => {
  const [columnSettingModalId, setColumnSettingModalId] = useState('');
  const [columnSettingModalOptions, setColumnSettingModalOptions] = useState({});

  return (
    <>
      <SortableListContainer
        useDragHandle
        disableAutoscroll
        helperClass="common-table-column-dragging"
        onSortEnd={({ oldIndex, newIndex }) => {
          if (oldIndex !== newIndex) {
            setProp((props) => {
              const nextColumns = arrayMoveImmutable(
                props.columns.slice(),
                oldIndex,
                newIndex,
              ).filter((item) => !!item);
              props.columns = nextColumns;
            }, 500);
          }
        }}
      >
        {columns.map(({ id, title, dataIndex, ...props }, index) => (
          <SortableListItem key={id} index={index} title={title}>
            <div className={styles.columnControlItem}>
              <SortableIcon />
              <div className={styles.columnControlItemInput}>
                <Input
                  size="small"
                  value={title}
                  bordered={false}
                  onChange={(e) => {
                    setProp((props) => {
                      const nextColumns = [...props.columns];
                      const index = _.findIndex(
                        nextColumns,
                        ({ id: currentId }) => currentId === id,
                      );
                      if (index > -1) {
                        nextColumns[index].title = e.target.value;
                        props.columns = nextColumns;
                      }
                    }, 500);
                  }}
                />
              </div>
              <div className={styles.columnControlItemInput}>
                <Input
                  size="small"
                  value={dataIndex}
                  bordered={false}
                  onChange={(e) => {
                    setProp((props) => {
                      const nextColumns = [...props.columns];
                      const index = _.findIndex(
                        nextColumns,
                        ({ id: currentId }) => currentId === id,
                      );
                      if (index > -1) {
                        nextColumns[index].dataIndex = e.target.value;
                        props.columns = nextColumns;
                      }
                    }, 500);
                  }}
                />
              </div>
              <div className={styles.columnControlItemActions}>
                <SettingOutlined
                  onClick={() => {
                    setColumnSettingModalId(id);
                    setColumnSettingModalOptions({ ...props, title });
                  }}
                />
                <MinusCircleOutlined
                  onClick={() => {
                    setProp((props) => {
                      const nextColumns = [...props.columns];
                      const index = _.findIndex(
                        nextColumns,
                        ({ id: currentId }) => currentId === id,
                      );
                      if (index > -1) {
                        nextColumns.splice(index, 1);
                        props.columns = nextColumns;
                      }
                    }, 500);
                  }}
                />
              </div>
            </div>
          </SortableListItem>
        ))}
      </SortableListContainer>

      <ColumnSettingModal
        visibleId={columnSettingModalId}
        options={columnSettingModalOptions}
        setProp={setProp}
        closeModal={() => {
          setColumnSettingModalOptions({});
          setColumnSettingModalId('');
        }}
      />
    </>
  );
};

export default ({ header, columns, tableSize, indexRender, setProp }) => {
  return (
    <>
      <div className={styles.headerControl}>
        <div>表格头部：</div>
        <div className={styles.headerItemControl}>
          <span>标&nbsp;&nbsp;&nbsp;&nbsp;题：</span>
          <Input
            size="small"
            value={header.headerTitle || ''}
            onChange={(e) => {
              setProp((props) => (props.header.headerTitle = e.target.value), 500);
            }}
            placeholder="请输入标题"
          />
        </div>
        <div className={styles.headerItemControl}>
          <span>工具栏：</span>
          <Radio.Group
            size="small"
            value={!!header.headerToolsRender}
            options={[
              { label: '显示', value: true },
              { label: '隐藏', value: false },
            ]}
            onChange={(e) => {
              setProp((props) => (props.header.headerToolsRender = e.target.value), 500);
            }}
          />
        </div>
      </div>
      <div className={styles.sizeControl}>
        <div>表格尺寸：</div>
        <Radio.Group
          size="small"
          optionType="button"
          value={tableSize}
          options={sizeOptions}
          onChange={(e) => {
            setProp((props) => (props.tableSize = e.target.value), 500);
          }}
        />
      </div>
      <div className={styles.indexRenderControl}>
        <div>渲染序号：</div>
        <Radio.Group
          size="small"
          value={indexRender}
          options={[
            { label: '渲染', value: true },
            { label: '隐藏', value: false },
          ]}
          onChange={(e) => {
            setProp((props) => (props.indexRender = e.target.value), 500);
          }}
        />
      </div>
      <div className={styles.columnControl}>
        <div>列设置：</div>
        <div className={styles.columnControlList}>
          <div className={styles.columnControlListTitle}>
            <span>标题</span>
            <span>code</span>
            <span>操作</span>
          </div>
          <SortableColumns columns={columns} setProp={setProp} />
          <DebounceButton
            size="small"
            type="dashed"
            onClick={() => {
              setProp(
                (props) =>
                  (props.columns = [...props.columns, { align: 'center', id: nanoid(12) }]),
                500,
              );
            }}
          >
            添加列
          </DebounceButton>
        </div>
      </div>
    </>
  );
};
